﻿/**************************************************************
* Copyright (C) 2022 www.eipflow.com 孙泽伟版权所有(盗版必究)
*
* 作者: 孙泽伟(QQ 1039318332)
* 创建时间: 2022/01/12 22:40:15
* 文件名: 
* 描述: 
* 
* 修改历史
* 修改人：
* 时间：
* 修改说明：
*
**************************************************************/
using EIP.Base.Models.Resx;
using EIP.Common.Controller.Attribute;
using EIP.Common.Core;
using EIP.Common.Core.Auth;
using EIP.Common.Extension;
using EIP.Common.JwtAuthorize;
using EIP.Common.Log.Handler;
using EIP.Common.Models;
using EIP.Common.Models.Dtos;
using EIP.Common.Models.Dtos.Reports;
using EIP.System.Logic;
using EIP.System.Models.Dtos.Login;
using EIP.System.Models.Dtos.Organization;
using EIP.System.Models.Dtos.Permission;
using EIP.System.Models.Dtos.User;
using EIP.System.Models.Enums;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace EIP.System.Controller
{
    /// <summary>
    /// 用户管理:此用户为系统使用人员,系统的人员管理在其他模块进行管理(如:人事管理HR)
    /// 此模块只维护基础信息
    /// </summary>
    public class UserController : BaseSystemController
    {
        #region 构造函数

        private readonly ISystemPermissionUserLogic _permissionUserLogic;
        private readonly ISystemUserInfoLogic _userInfoLogic;
        private readonly ISystemOrganizationLogic _organizationLogic;
        private readonly ISystemPermissionLogic _permissionLogic;
        readonly ITokenBuilder _tokenBuilder;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tokenBuilder"></param>
        /// <param name="userInfoLogic"></param>
        /// <param name="permissionUserLogic"></param>
        /// <param name="organizationLogic"></param>
        /// <param name="permissionLogic"></param>
        public UserController(ITokenBuilder tokenBuilder, ISystemUserInfoLogic userInfoLogic,
            ISystemPermissionUserLogic permissionUserLogic,
            ISystemOrganizationLogic organizationLogic,
            ISystemPermissionLogic permissionLogic)
        {

            _permissionUserLogic = permissionUserLogic;
            _organizationLogic = organizationLogic;
            _permissionLogic = permissionLogic;
            _userInfoLogic = userInfoLogic;
            _tokenBuilder = tokenBuilder;
        }

        #endregion

        #region 方法

        /// <summary>
        /// 分页获取所有用户信息
        /// </summary>
        /// <param name="input">用户信息分页参数</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-分页获取所有用户信息", RemarkFrom.System)]
        [Route("/system/user/list")]
        public async Task<JsonResult> Find(SystemUserPagingInput input)
        {
            #region 获取权限控制器信息
            input.DataSql = (await _permissionLogic.FindDataPermissionSql(new ViewRote { UserId = CurrentUser.UserId, MenuId = ResourceMenuId.系统用户.ToGuid() })).Data;
            #endregion
            return JsonForGridPaging(await _userInfoLogic.Find(input));
        }

        /// <summary>
        /// 读取组织机构树
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [CreateBy("孙泽伟")]
        [Remark("组织机构维护-方法-列表-读取组织机构树", RemarkFrom.System)]
        [Route("/system/user/organization")]
        public async Task<JsonResult> FindOrganization()
        {
            #region 获取权限控制器信息
            SystemOrganizationDataPermissionInput input = new SystemOrganizationDataPermissionInput
            {
                PrincipalUser = CurrentUser,
                DataSql = (await _permissionLogic.FindDataPermissionSql(new ViewRote
                {
                    UserId = CurrentUser.UserId,
                    MenuId = ResourceMenuId.系统用户.ToGuid()
                })).Data
            };
            #endregion
            return JsonForTree((await _organizationLogic.FindDataPermission(input)).Data.ToList());
        }

        /// <summary>
        /// 根据主键获取用户信息
        /// </summary>
        /// <param name="input">用户Id</param>
        /// <returns></returns>
        [HttpGet]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-根据主键获取用户信息", RemarkFrom.System)]
        [Route("/system/user/{id}")]
        public async Task<JsonResult> FindById([FromRoute] IdInput input)
        {
            return Json(await _userInfoLogic.FindById(input));
        }

        /// <summary>
        /// 检测代码是否已经具有重复项
        /// </summary>
        /// <param name="input">需要验证的参数</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-新增/编辑-检测代码是否已经具有重复项", RemarkFrom.System)]
        [Route("/system/user/checkcode")]
        public async Task<JsonResult> CheckCode(SystemUserCheckUserCodeInput input)
        {
            return Json(await _userInfoLogic.CheckCode(input));
        }

        /// <summary>
        /// 保存人员数据
        /// </summary>
        /// <param name="input">人员信息</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-新增/编辑-保存", RemarkFrom.System)]
        [Route("/system/user")]
        public async Task<JsonResult> Save(SystemUserSaveInput input)
        {
            return Json(await _userInfoLogic.Save(input));
        }

        /// <summary>
        /// 删除人员数据
        /// </summary>
        /// <param name="input">人员Id</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-删除", RemarkFrom.System)]
        [Route("/system/user/{id}")]
        public async Task<JsonResult> Delete(IdInput<string> input)
        {
            return Json(await _userInfoLogic.Delete(input));
        }

        /// <summary>
        /// 根据用户Id获取用户详细情况
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-根据用户Id获取用户详细情况", RemarkFrom.System)]
        [Route("/system/user/detail/{id}")]
        public async Task<JsonResult> FindDetailByUserId([FromRoute] IdInput input)
        {
            return Json(await _userInfoLogic.FindDetailByUserId(input));
        }

        /// <summary>
        /// 根据用户Id重置某人密码
        /// </summary>
        /// <param name="input">用户Id</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-重置密码", RemarkFrom.System)]
        [Route("/system/user/resetpassword")]
        public async Task<JsonResult> ResetPassword(SystemUserResetPasswordInput input)
        {
            return Json(await _userInfoLogic.ResetPassword(input));
        }

        /// <summary>
        /// 保存用户头像
        /// </summary>
        /// <param name="input">用户Id</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-保存用户头像", RemarkFrom.System)]
        [Route("/system/user/headimage")]
        public async Task<JsonResult> SaveHeadImage(IdInput<string> input)
        {
            //将上传的base64字符串保存为图片
            return Json(await _userInfoLogic.SaveHeadImage(new SystemUserSaveHeadImageInput
            {
                HeadImage = input.Id,
                UserId = CurrentUser.UserId
            }));
        }

        /// <summary>
        /// 保存用户信息
        /// </summary>
        /// <param name="privilegeMasterUser">用户json字符串</param>
        /// <param name="privilegeMasterValue">角色信息</param>
        /// <param name="privilegeMaster">归属人员类型:组织机构、角色、岗位、组</param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-保存权限用户信息", RemarkFrom.System)]
        [Route("/system/user/privilegemaster")]
        public async Task<JsonResult> SavePrivilegeMasterUser(string privilegeMasterUser,
            Guid privilegeMasterValue,
            EnumPrivilegeMaster privilegeMaster)
        {
            var models = JsonConvert.DeserializeObject<IList<SystemPermissionSaveUserInput>>(privilegeMasterUser);
            IList<Guid> users = models.Select(m => m.U).ToList();
            return Json(await _permissionUserLogic.SavePermissionUserBeforeDelete(privilegeMaster, privilegeMasterValue, users));
        }

        /// <summary>
        /// 保存修改密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-保存修改后密码信息", RemarkFrom.System)]
        [Route("/system/user/changepassword")]
        public async Task<JsonResult> SaveChangePassword(SystemUserChangePasswordInput input)
        {
            input.UserId = CurrentUser.UserId;
            return Json(await _userInfoLogic.SaveChangePassword(input));
        }

        /// <summary>
        /// 验证旧密码是否输入正确
        /// </summary>
        /// <param name="input">需要验证的参数</param>
        /// <returns></returns>
        [HttpGet]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-验证旧密码是否输入正确", RemarkFrom.System)]
        [Route("/system/user/checkoldpassword")]
        public async Task<JsonResult> CheckOldPassword([FromRoute] CheckSameValueInput input)
        {
            input.Id = CurrentUser.UserId;
            return Json(await _userInfoLogic.CheckOldPassword(input));
        }

        /// <summary>
        /// 冻结
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-冻结", RemarkFrom.System)]
        [Route("/system/user/isfreeze")]
        public async Task<JsonResult> IsFreeze(IdInput input)
        {
            return Json(await _userInfoLogic.IsFreeze(input));
        }

        /// <summary>
        /// 查看具有特权的人员
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户控件-视图-查看具有特权的人员", RemarkFrom.System)]
        [Route("/system/user/toporg")]
        public async Task<JsonResult> FindTopOrg(SystemUserFindTopOrgInput input)
        {
            return Json((await _userInfoLogic.Find(new SystemUserPagingInput
            {
                DataSql = " 1=1 ",
                Size = 99999999,
                PrivilegeMaster = EnumPrivilegeMaster.组织架构,
                TopOrg = input.TopOrg
            })).Data);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [RequestSizeLimit(100_000_000)]//最大100m左右
        public async Task<JsonResult> UploadHeadImage(SystemUserSaveInput input)
        {
            input.Files = Request.Form.Files;
            return Json(await _userInfoLogic.UploadHeadImage(input));
        }

        #endregion

        #region 登录
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        [Route("/authorize/account/captcha")]
        public IActionResult Captcha()
        {
            return File(_userInfoLogic.Captcha().Data, "image/gif");
        }
        /// <summary>
        /// 授权中心登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [Route("/authorize/account/login")]
        public async Task<JsonResult> Login(SystemLoginInput input)
        {
            string token;
            var info = await _userInfoLogic.Login(input);
            if (info.Data != null)
            {
                var loginTime = DateTime.Now;
                var ip = HttpContext.Features.Get<Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature>()?.RemoteIpAddress?.ToString();
                var claims = new[]
                {
                    new Claim("Name", info.Data.Name),
                    new Claim("IsAdmin", info.Data.IsAdmin.ToString()),
                    new Claim("Code", info.Data.Code),
                    new Claim("OrganizationId", info.Data.OrganizationId==Guid.Empty?"":info.Data.OrganizationId.ToString()),
                    new Claim("OrganizationName", info.Data.OrganizationName ?? ""),
                    new Claim("LoginId", info.Data.LoginId.ToString()),
                    new Claim("RemoteIp", input.RemoteIp),
                    new Claim("RemoteIpAddress", input.RemoteIpAddress),
                    new Claim("Navigator", input.Navigator),
                    new Claim(JwtRegisteredClaimNames.Jti, info.Data.UserId.ToString())
                    };
                token = _tokenBuilder.BuildJwtToken(claims, ip, DateTime.UtcNow, loginTime.AddDays(1)).TokenValue;
            }
            else
            {
                return Json(OperateStatus.Error(info.Msg.ToString()));
            }
            await WriteLoginLog(info.Data, input);
            return Json(new
            {
                Code = ResultCode.Success,
                Msg = "登录成功",
                Data = new
                {
                    UserId = info.Data.UserId,
                    Code = info.Data.Code,
                    OrganizationId = info.Data.OrganizationId,
                    Token = token,
                    Name = info.Data.Name,
                    OrganizationName = info.Data.OrganizationName,
                    HeadImage = info.Data.HeadImage,
                    Expire = (long)(DateTime.Now.AddDays(1) - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1))).TotalSeconds
                }
            });
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("主界面-方法-退出", RemarkFrom.System)]
        [Route("/authorize/account/logout")]
        public async Task<JsonResult> LoginOut()
        {
            try
            {
                ////修改时间
                //if (CurrentUser != null)
                //    _loginLogLogic.LoginOut(new IdInput(CurrentUser.LoginId));
            }
            catch (EipException e)
            {
                return Json(OperateStatus.Error(e.Message));
            }
            //operateStatus.Message = ResourceSystem.退出成功;
            return Json(OperateStatus.Success());
        }

        /// <summary>
        /// 写登录日志
        /// </summary>
        /// <param name="loginOutput"></param>
        /// <param name="loginInput"></param>
        /// <returns></returns>
        [HttpPost]
        private async Task WriteLoginLog(SystemLoginOutput loginOutput, SystemLoginInput loginInput)
        {
            //发送信息给客户端
            LoginLogHandler handler = new LoginLogHandler(new PrincipalUser
            {
                RemoteIp = loginInput.RemoteIp,
                RemoteIpAddress = loginInput.RemoteIpAddress,
                Navigator = loginInput.Navigator,
                Code = loginOutput.Code,
                UserId = loginOutput.UserId,
                Name = loginOutput.Name
            }, loginOutput.LoginId);
            //通知所有人
            //var converter = new IsoDateTimeConverter();
            //converter.DateTimeFormat = "yyyy-MM-dd hh:mm:ss";
            //_hubContext.Clients.All.SendAsync("ReceiveSendToLogin", JsonConvert.SerializeObject(handler.Log, converter));
            //写入日志
            handler.WriteLog();
        }

        #endregion

        #region 注册

        #endregion

        #region 导入导出
        /// <summary>
        /// 导出到Excel
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-列表-导出到Excel", RemarkFrom.System)]
        public FileResult ExportExcel(SystemUserPagingInput paging)
        {
            ExcelReportDto excelReportDto = new ExcelReportDto()
            {
                //TemplatePath = Server.MapPath("/") + "Templates/System/User/用户导出模版.xlsx",
                DownTemplatePath = "用户信息" + string.Format("{0:yyyyMMddHHmmssffff}", DateTime.Now) + ".xlsx",
                Title = "用户信息.xlsx"
            };
            _userInfoLogic.ReportExcelUserQuery(paging, excelReportDto);
            //return File(new FileStream(excelReportDto.DownPath, FileMode.Open), "application/octet-stream", Server.UrlEncode(excelReportDto.Title));
            return null;
        }

        /// <summary>
        /// 下载用户导入模版
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-下载用户导入模版", RemarkFrom.System)]
        [Route("/system/user/import/template")]
        public async Task<FileResult> DownImportTemplate()
        {
            return await GenerateTemplate<SystemUserImportDto>();
        }

        /// <summary>
        /// 导出人员:生成excel文件
        /// </summary>
        /// <param name="input">查询参数</param>
        /// <returns></returns>
        [HttpPost]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-导入人员", RemarkFrom.System)]
        [Route("/system/user/export")]
        public async Task<FileResult> ExportUser(SystemUserPagingInput input)
        {
            #region 获取权限控制器信息
            input.Size = int.MaxValue;
            input.DataSql = (await _permissionLogic.FindDataPermissionSql(new ViewRote { UserId = CurrentUser.UserId, MenuId = ResourceMenuId.系统用户.ToGuid() })).Data;
            #endregion
            var users = (await _userInfoLogic.Find(input)).Data.Data;
            return await Export(users);
        }

        /// <summary>
        /// 导入人员
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        [CreateBy("孙泽伟")]
        [Remark("用户维护-方法-导入人员", RemarkFrom.System)]
        [Route("/system/user/import")]
        public async Task<JsonResult> ImportUser()
        {
            var result = await Import<SystemUserImportDto>();
            if (result.Code == ResultCode.Success)
            {
                return Json(await _userInfoLogic.ImportUser(result.Data));
            }
            else
            {
                return Json(result);
            }
        }

        #endregion
    }
}